﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FF14TreasureDiggingTool.DataAccess.ApplicationDbContext;
using FF14TreasureDiggingTool.DataAccess.Enums;
using FF14TreasureDiggingTool.DataAccess.Models;
using Microsoft.EntityFrameworkCore;
using System.Collections.ObjectModel;
using System.Linq;
using Wpf.Ui.Common.Interfaces;
using Wpf.Ui.Controls.Interfaces;
using Wpf.Ui.Mvvm.Contracts;

namespace FF14TreasureDiggingTool.ViewModels;

public partial class EventViewModel : ObservableObject, INavigationAware
{
    private readonly ApplicationContext _dbContext;
    private readonly ISnackbarControl _snackbarControl;

    private bool _isInitialized;

    [ObservableProperty]
    private string _eventContent;

    [ObservableProperty]
    private int? _sortNum;

    [ObservableProperty]
    private CustomRule _selectedRule;

    private ObservableCollection<SpecialEvent> _enemyEvents;

    public ObservableCollection<SpecialEvent> EnemyEvents
    {
        get => _enemyEvents;
        set => SetProperty(ref _enemyEvents, value);
    }

    private ObservableCollection<SpecialEvent> _treasureEvents;

    public ObservableCollection<SpecialEvent> TreasureEvents
    {
        get => _treasureEvents;
        set => SetProperty(ref _treasureEvents, value);
    }

    private ObservableCollection<SpecialEvent> _strongDesireEvents;

    public ObservableCollection<SpecialEvent> StrongDesireEvents
    {
        get => _strongDesireEvents;
        set => SetProperty(ref _strongDesireEvents, value);
    }

    private ObservableCollection<CustomRule> _customRules;

    public ObservableCollection<CustomRule> CustomRules
    {
        get => _customRules;
        set => SetProperty(ref _customRules, value);
    }

    [ObservableProperty]
    private bool _isLeftChecked;

    [ObservableProperty]
    private bool _isRightChecked;

    public EventViewModel(ApplicationContext dbContext, ISnackbarService snackbarService)
    {
        _dbContext = dbContext;
        _snackbarControl = snackbarService.GetSnackbarControl();
    }

    public void OnNavigatedTo()
    {
        if (!_isInitialized)
        {
            InitializeViewlModel();
        }
    }

    public void OnNavigatedFrom()
    { }

    private void InitializeViewlModel()
    {
        CustomRules = new ObservableCollection<CustomRule>(
            _dbContext.CustomRules
                .Include(r => r.FloorInfos)
                .ThenInclude(f => f.RouteOptions)
                .Include(c => c.TotalEvents)
                .ToList()
        );
        SelectedRule = CustomRules.First();
        EventContent = string.Empty;

        if (SelectedRule.TotalEvents.Count < 3)
        {
            EnemyEvents = new ObservableCollection<SpecialEvent>();
            TreasureEvents = new ObservableCollection<SpecialEvent>();
            StrongDesireEvents = new ObservableCollection<SpecialEvent>();
        }
        else
        {
            EnemyEvents = new ObservableCollection<SpecialEvent>(
                SelectedRule.TotalEvents
                    .Where(e => e.EventType == EventType.EnemyEvent)
                    .ToList()
                    .OrderBy(e => e.Sort)
            );
            TreasureEvents = new ObservableCollection<SpecialEvent>(
                SelectedRule.TotalEvents
                    .Where(e => e.EventType == EventType.TreasureEvent)
                    .ToList()
                    .OrderBy(e => e.Sort)
            );
            StrongDesireEvents = new ObservableCollection<SpecialEvent>(
                SelectedRule.TotalEvents
                    .Where(e => e.EventType == EventType.StrongDesireEvent)
                    .ToList()
                    .OrderBy(e => e.Sort)
            );
        }
    }

    [RelayCommand]
    public void LoadEvents()
    {
        if (SelectedRule != null)
        {
            if (SelectedRule.TotalEvents.Count < 3)
            {
                EnemyEvents = new ObservableCollection<SpecialEvent>();
                TreasureEvents = new ObservableCollection<SpecialEvent>();
                StrongDesireEvents = new ObservableCollection<SpecialEvent>();
            }
            else
            {
                EnemyEvents = new ObservableCollection<SpecialEvent>(
                    SelectedRule.TotalEvents
                        .Where(e => e.EventType == EventType.EnemyEvent)
                        .ToList()
                        .OrderBy(e => e.Sort)
                );
                TreasureEvents = new ObservableCollection<SpecialEvent>(
                    SelectedRule.TotalEvents
                        .Where(e => e.EventType == EventType.TreasureEvent)
                        .ToList()
                        .OrderBy(e => e.Sort)
                );
                StrongDesireEvents = new ObservableCollection<SpecialEvent>(
                    SelectedRule.TotalEvents
                        .Where(e => e.EventType == EventType.StrongDesireEvent)
                        .ToList()
                        .OrderBy(e => e.Sort)
                );
            }
        }
    }

    [RelayCommand]
    public void AddSpecialEvent(string eventType)
    {
        if (string.IsNullOrEmpty(EventContent))
        {
            _snackbarControl.Show("添加失败", "事件名称为空");
            return;
        }

        if (!IsLeftChecked && !IsRightChecked)
        {
            _snackbarControl.Show("添加失败", "未选择事件系数");
            return;
        }

        if (SortNum is null)
        {
            _snackbarControl.Show("添加失败", "排序序号为空");
            return;
        }

        var toAddEvent = new SpecialEvent();
        toAddEvent.EventName = EventContent;
        toAddEvent.Sort = (int)SortNum;
        toAddEvent.Factor = IsLeftChecked ? 0 : 1;

        switch (eventType)
        {
            case "enemyEvent":
                toAddEvent.EventType = EventType.EnemyEvent;
                EnemyEvents.Add(toAddEvent);
                break;

            case "treasureEvent":
                toAddEvent.EventType = EventType.TreasureEvent;
                TreasureEvents.Add(toAddEvent);
                break;

            case "strongDesireEvent":
                toAddEvent.EventType = EventType.StrongDesireEvent;
                StrongDesireEvents.Add(toAddEvent);
                break;
        }
    }

    [RelayCommand]
    public void SaveEdit()
    {
        if (EnemyEvents.Count == 0 || TreasureEvents.Count == 0 || StrongDesireEvents.Count == 0)
        {
            _snackbarControl.Show("事件不能为空，请为每种类型事件至少添加一条记录");
            return;
        }

        SelectedRule.TotalEvents.Clear();
        SelectedRule.TotalEvents.AddRange(EnemyEvents);
        SelectedRule.TotalEvents.AddRange(TreasureEvents);
        SelectedRule.TotalEvents.AddRange(StrongDesireEvents);

        _dbContext.Update(SelectedRule);
        _dbContext.SaveChanges();
        _snackbarControl.Show("保存成功");

        CustomRules = new ObservableCollection<CustomRule>(
            _dbContext.CustomRules
                .Include(r => r.FloorInfos)
                .ThenInclude(f => f.RouteOptions)
                .Include(c => c.TotalEvents)
                .ToList()
        );
        SelectedRule = CustomRules.First();
    }

    [RelayCommand]
    public void RemoveEnemyEvent(SpecialEvent specialEvent)
    {
        EnemyEvents.Remove(specialEvent);
    }

    [RelayCommand]
    public void RemoveTrasureEvent(SpecialEvent specialEvent)
    {
        TreasureEvents.Remove(specialEvent);
    }

    [RelayCommand]
    public void RemoveStrongDesireEvent(SpecialEvent specialEvent)
    {
        StrongDesireEvents.Remove(specialEvent);
    }
}